package com.elecbook.content.service;

import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.elecbook.auth.model.po.User;
import com.elecbook.base.dto.PageDTO;
import com.elecbook.base.constant.CommentJudgeStateConstant;
import com.elecbook.base.enums.OperationType;
import com.elecbook.base.exception.BaseInfoException;
import com.elecbook.base.result.Result;
import com.elecbook.base.util.SecurityUtil;
import com.elecbook.base.util.TimeFillUtil;
import com.elecbook.content.mapper.CommentMapper;
import com.elecbook.content.mapper.CommentjudgeMapper;
import com.elecbook.content.mapper.ContributeMapper;
import com.elecbook.content.model.dto.CommentPQuery;
import com.elecbook.content.model.dto.CommentSubmitDTO;
import com.elecbook.content.model.dto.CommentUpdateDTO;
import com.elecbook.content.model.dto.CommnetPageDTO;
import com.elecbook.content.model.po.Comment;
import com.elecbook.content.model.po.Commentjudge;
import com.elecbook.content.model.po.Contribute;
import com.elecbook.content.model.vo.CommentVO;
import com.elecbook.rpc.feignclient.UserServiceClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 评论 服务实现类
 * </p>
 *
 * @author Z-ken
 * @since 2024/11/05 15:50:50
 */
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private CommentjudgeMapper commentjudgeMapper;
    @Autowired
    private ContributeMapper contributeMapper;
    @Autowired
    private UserServiceClient userServiceClient;


    @Override
    public CommentVO submitComment(CommentSubmitDTO dto) {
        if (StringUtils.isBlank(dto.getContent())) {
            throw new BaseInfoException("评论内容不能为空");
        }

        if (dto.getContributeId() == null) {
            throw new BaseInfoException("未指定评论的电子书籍");
        }
        Contribute contribute = contributeMapper.selectById(dto.getContributeId());
        if (contribute == null) {
            throw new BaseInfoException("评论非法的电子书籍");
        }

        // 复制comment的内容
        Comment comment = new Comment();
        BeanUtils.copyProperties(dto, comment);
        TimeFillUtil.fillTimeAndCreateUser(comment, OperationType.INSERT);

        Integer userId = SecurityUtil.getCurrentId();
        // 用户id填写
        comment.setUserId(userId);

        if (SecurityUtil.hasAuthority("ADMIN")) {
            comment.setJudgeState(CommentJudgeStateConstant.ACCEPT);
        } else {
            comment.setJudgeState(CommentJudgeStateConstant.SUBMIT);
        }
        commentMapper.insert(comment);
        Commentjudge commentjudge = new Commentjudge();
        BeanUtils.copyProperties(comment, commentjudge);
        commentjudge.setCommentId(comment.getId());
        commentjudgeMapper.insert(commentjudge);

        // 添加返回的内容
        List<Integer> ids = new ArrayList<>();
        ids.add(SecurityUtil.getCurrentId());
        Result<List<User>> result = userServiceClient.getUserInfoByIds(ids);
        if (result.getCode() == 0) {
            throw new BaseInfoException("内容RPC请求错误");
        }
        List<User> userList = result.getData();
        User user = userList.get(0);
        CommentVO vo = new CommentVO();
        BeanUtils.copyProperties(comment, vo);
        // 写入用户信息
        vo.setUserAvatar(user.getAvatar());
        vo.setUsername(user.getName());

        return vo;
    }

    @Override
    public PageDTO<CommentVO> queryCommentPage(CommnetPageDTO pageDTO) {
        // 1.添加排序规则
        // 使用内置的函数转换并且 设置规则
        List<OrderItem> orderItems = pageDTO.toMpOrderItems();

        // 设计vo，获取用户头像和用户姓名信息
        // 获取分页对象和排序情况
        //  普通字段分页，然后返回VO结果
        Page<Comment> page = pageDTO.toMpPageDefaultSortByIdAsc(orderItems.toArray(new OrderItem[0]));
        /*
        查询, 自定义的分页查询
         */
        Page<CommentVO> p = baseMapper.selectPageVO(page, pageDTO);

        // 获取额外数据内容
        Set<Integer> idsSet = new HashSet<>();
        p.getRecords().forEach(item -> idsSet.add(item.getUserId()));
        List<Integer> ids = new ArrayList<>(idsSet);
        // 调用user的feign进行获取用户信息
        Result<List<User>> result = userServiceClient.getUserInfoByIds(ids);
        List<User> userList = result.getData();
        if (result.getCode() == 0) {
            throw new BaseInfoException("内容RPC请求错误");
        }
        // 将 userList 转换为 Map，key 为 userId，value 为 User 对象
        // Function.identity()是一个返回对象本身的函数
        Map<Integer, User> userMap = userList.stream()
                .collect(Collectors.toMap(User::getId, Function.identity()));

        // 回填新的record
        // TODO 修复错误 java.lang.ClassCastException: com.elecbook.content.model.po.Comment cannot be cast to com.elecbook.content.model.vo.CommentVO
        List<CommentVO> records = p.getRecords();
        records.forEach(item -> {
            User user = userMap.get(item.getUserId());
            // 回填数据
            item.setUsername(user.getName());
            item.setUserAvatar(user.getAvatar());
        });
        // 设置回填后的list
        p.setRecords(records);
        // 获取数据信息
        return PageDTO.of(p, CommentVO.class);
    }

    @Override
    public Comment updateByDto(CommentUpdateDTO dto) {
        Comment comment = commentMapper.selectById(dto.getId());
        BeanUtils.copyProperties(dto, comment);
        commentMapper.updateById(comment);
        return comment;
    }

    @Override
    public void deleteByDto(CommentUpdateDTO dto) {
        commentMapper.deleteById(dto.getId());
    }


    /**
     * 基础分页请求--管理员
     */
    @Override
    public PageDTO<Comment> pageQuery(CommentPQuery query) {
        // 1.添加排序规则
        // 使用内置的函数转换并且 设置规则-这里为了方便扩展和使用先进行创建
        List<OrderItem> orderItems = query.toMpOrderItems();

        // 获取分页对象和排序情况
        Page<Comment> page = query.toMpPageDefaultSortByIdAsc(orderItems.toArray(new OrderItem[0]));
    /*
    查询
    */
        Page<Comment> p = baseMapper.selectPageEntity(page, query);

        // 获取数据信息
        return PageDTO.of(p, Comment.class);
    }


    @Override
    public Comment saveComment(Comment comment) {
        comment.setId(null);
        baseMapper.insert(comment);
        return comment;
    }

    @Override
    public Comment updateCommentById(Comment comment) {
        baseMapper.updateById(comment);
        return comment;
    }


}
